package com.orange.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.orange.user.common.ErrorCode;
import com.orange.user.exception.BusinessException;
import com.orange.user.mapper.UserMapper;
import com.orange.user.model.*;
import com.orange.user.service.UserService;
import com.orange.user.util.TokenUtil;
import com.orange.user.util.UserContext;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 丁铭杰
 * @description 针对表【user(用户)】的数据库操作Service实现
 * @createDate 2025-08-31 14:57:29
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService{
    @Resource
    private RedissonClient redissonClient;
    // 盐值，混淆密码
    public static final String SALT = "dmj";

    @Override
    public Long register(UserRegisterRequest userRegisterRequest) throws InterruptedException {
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        // 用户名和密码校验
        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名或密码为空");
        }
        if (userAccount.length() < 2) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名长度不能小于2");
        }
        // 两次输入密码相同
        if (!userPassword.equals(checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入密码不相同");
        }
        // 加分布式锁
        RLock lock = redissonClient.getLock("lock:userAccount:" + userAccount);
        boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
        if (isLock) {
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getUserAccount, userAccount);
            long count = this.count(queryWrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名已存在");
            }
            // 对密码进行加密
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
            User user = new User();
            BeanUtil.copyProperties(userRegisterRequest, user);
            user.setUserPassword(encryptPassword);
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            user.setIsDelete(0);
            // save
            boolean saveResult = this.save(user);
            if (!saveResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "用户注册失败");
            }
            log.info("用户 {} 注册成功", user.getUserAccount());
            lock.unlock();
            return user.getId();
        } else {
            return null;
        }
    }

    @Override
    public String login(String username, String password) {
        // 参数校验
        if (StringUtils.isAnyBlank(username, password)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名或密码为空");
        }
        // 密码校验
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>();
        queryWrapper.eq(User::getUserAccount, username)
                .eq(User::getUserPassword, encryptPassword)
                .ne(User::getIsDelete, 1);
        User user = getOne(queryWrapper);
        if (user == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名或密码错误");
        }
        log.info("用户 {} 登录成功", user.getUserAccount());
        return TokenUtil.sign(username);
    }

    @Override
    public String update(UserUpdateRequest userUpdateRequest) {
        String userAccount = userUpdateRequest.getUserAccount();
        String userName = userUpdateRequest.getUserName();
        String userAvatar = userUpdateRequest.getUserAvatar();
        String userProfile = userUpdateRequest.getUserProfile();

        String userAccountLocal = UserContext.getUserAccount();
        if (!Objects.equals(userAccount, userAccountLocal)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名不一致");
        }
        // 更新数据库
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getUserAccount, userAccount).ne(User::getIsDelete, 1);
        updateWrapper.set(StringUtils.isNotEmpty(userName), User::getUserName, userName)
                .set(StringUtils.isNotEmpty(userAvatar), User::getUserProfile,userAvatar)
                .set(StringUtils.isNotEmpty(userProfile), User::getUserAvatar, userProfile)
                .set(User::getUpdateTime, new Date());
        boolean result = this.update(updateWrapper);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新失败");
        }
        log.info("用户 {} 信息修改成功", userAccount);
        return userAccount;
    }

    @Override
    public String delete() {
        String userAccount = UserContext.getUserAccount();
        // 逻辑删除
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getUserAccount, userAccount)
                .ne(User::getIsDelete, 1)
                .set(User::getIsDelete, 1)
                .set(User::getUpdateTime, new Date());
        boolean result = this.update(updateWrapper);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除失败");
        }
        log.info("用户 {} 删除成功", userAccount);
        return userAccount;
    }

    @Override
    public User queryByAccount(String userAccount) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserAccount, userAccount)
                .ne(User::getIsDelete, 1);
        return getOne(queryWrapper);
    }


    @Override
    public UserVO getUserVO(User user) {
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public List<UserVO> pageUsers(short page, short size) {
        Page<User> pageUser = new Page<>(page, size);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(User::getIsDelete, 1).orderByDesc(User::getUpdateTime);
        IPage<User> userIPage = this.page(pageUser, queryWrapper);
        return userIPage.getRecords().stream().map(this::getUserVO).collect(Collectors.toList());
    }

    @Override
    public TokenValidationResponse validateToken(TokenValidationRequest request) {
        String userAccount = TokenUtil.getUserAccountFromToken(request.getToken());
        if (StringUtils.isNotEmpty(userAccount)){
            System.out.println("token is valid");
            return new TokenValidationResponse(true,userAccount);
        }
        else return new TokenValidationResponse(false,"");
    }
}




